package ca.uwindsor.cs.deepweb.estimation.method.capturehistory;

import java.util.HashSet;
import java.util.Random;

public class RandomSimulation {
	protected short times;
	protected HashSet<Integer> unique;
	protected int total;
	protected int marked;
	protected int corpussize;
	protected int maxstepsize;
	protected Random r;
	protected StringBuilder result;

	/**
	 * @param corpussize
	 * @param times
	 * 
	 */
	public RandomSimulation(int corpussize, short times) {
		this.corpussize = corpussize;
		this.times = times;
		result = new StringBuilder();
		r = new Random();
		unique = new HashSet<Integer>();
	}

	public void query() throws Exception {
		HashSet<Integer> newid;
		HashSet<Integer> duplicated = new HashSet<Integer>();
		double nominator = 0;
		double denominator = 0;
		int orresult;
		double OR;
		int temp;
		float exponentofOR = -2.1f;
		double ratio;
		double precetage;

		for (int i = 0; i < times; i++) {
			// priorunique = unique.size();
			do {
//				temp = r.nextInt(40);
				temp = 100;
			} while (temp == 0);

			newid = getReturns(temp);
			total += newid.size();

			duplicated.clear();
			duplicated.addAll(newid);
			duplicated.retainAll(unique);
			marked = duplicated.size();

			unique.addAll(newid);

			//
			ratio = duplicated.size() / (double) newid.size();
			precetage = unique.size() / (double) corpussize;
			//

			//
			nominator += newid.size() * unique.size() * unique.size();
			denominator += marked * unique.size();
			//

			//
			OR = total / (float) unique.size();
			orresult = (int) (unique.size() / (1 - Math.pow(OR, exponentofOR)));
			//
			result.append(i + "\t" + newid.size() + "\t" + duplicated.size()
					+ "\t" + unique.size() + "\t" + ratio + "\t" + precetage + "\t"
					+ (int) (nominator / denominator) + "\t" + orresult + "\n");
		}
	}

	protected HashSet<Integer> getReturns(int numberofreturns) {
		HashSet<Integer> l = new HashSet<Integer>(numberofreturns);
		for (int i = 0; i < numberofreturns; i++) {
			l.add(r.nextInt(corpussize));
		}
		return l;
	}

	public String toString() {
		return result.toString();
	}

	public static void main(String[] args) {
		RandomSimulation rs = new RandomSimulation(2000, (short) 30);
		try {
			rs.query();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(rs.toString());
	}
}
